// Package alipay 支付宝扩展包
package alipay

import (
	"github.com/smartwalle/alipay/v3"
	"log"
	"net/http"
	"strconv"
)

type AliPkg struct {
	AppId      string //appid
	PrivateKey string //私钥
	PublicKey  string //支付宝公钥
	PayModel   string //支付方式h5、pc扫码
}

// GoPay 发起支付
func (pkg *AliPkg) GoPay(payInfo map[string]string) map[string]interface{} {
	paystr := make(map[string]interface{})
	appid := pkg.AppId
	PrivateKey := pkg.PrivateKey
	PublicKey := pkg.PublicKey
	var err error
	var aliClient *alipay.Client
	if aliClient, err = alipay.New(appid, PrivateKey, true); err != nil {
		log.Println("初始化支付宝失败", err)
		return nil
	}
	if err = aliClient.LoadAliPayPublicKey(PublicKey); err != nil {
		log.Println("加载证书发生错误", err)
		return nil
	}
	if pkg.PayModel == "h5" {
		var p = alipay.TradeWapPay{}
		p.NotifyURL = payInfo["notifyUrl"]
		p.Subject = payInfo["title"]
		p.OutTradeNo = payInfo["pay_id"]
		p.TotalAmount = payInfo["price"]
		p.ProductCode = "QUICK_WAP_WAY"
		url, _ := aliClient.TradeWapPay(p)
		paystr = map[string]interface{}{
			"h5URL":  url.String(),
			"payApp": "支付宝",
		}
	}
	if pkg.PayModel == "pc" {
		var p = alipay.TradePreCreate{}
		p.NotifyURL = payInfo["notifyUrl"]
		p.Subject = payInfo["title"]
		p.OutTradeNo = payInfo["pay_id"]
		p.TotalAmount = payInfo["price"]

		rsp, err := aliClient.TradePreCreate(p)
		if err != nil {
			log.Println(err)
			return nil
		}
		if rsp.Content.Code != alipay.CodeSuccess {
			log.Println(rsp.Content.Msg, rsp.Content.SubMsg)
			return nil
		}
		paystr = map[string]interface{}{
			"codeURL": rsp.Content.QRCode,
			"payApp":  "支付宝",
		}
	}

	return paystr
}

// Notify 支付结果
func (pkg *AliPkg) Notify(req *http.Request) map[string]string {
	payInfo := make(map[string]string)

	appid := pkg.AppId
	PrivateKey := pkg.PrivateKey
	PublicKey := pkg.PublicKey
	var aliClient *alipay.Client
	aliClient, _ = alipay.New(appid, PrivateKey, true)
	aliClient.LoadAliPayPublicKey(PublicKey)
	var res, _ = aliClient.GetTradeNotification(req)
	if res == nil {
		return nil
	}
	if res.TradeStatus == "TRADE_SUCCESS" {
		payInfo = map[string]string{
			"TotalFee":      res.TotalAmount,
			"TransactionID": res.TradeNo,
			"OutTradeNO":    res.OutTradeNo,
		}
		return payInfo
	}
	return nil
}

// Refund 退款
func (pkg *AliPkg) Refund(money float64, total_fee float64, tradeNo string, out_refund_no string, desc string) bool {
	if money <= 0 {
		money = total_fee
	}
	appid := pkg.AppId
	PrivateKey := pkg.PrivateKey
	PublicKey := pkg.PublicKey
	var aliClient *alipay.Client
	aliClient, _ = alipay.New(appid, PrivateKey, true)
	aliClient.LoadAliPayPublicKey(PublicKey)
	var p = alipay.TradeRefund{}
	p.RefundAmount = strconv.FormatFloat(money, 'f', 1, 64)
	p.TradeNo = tradeNo
	p.OutRequestNo = out_refund_no
	p.RefundReason = desc
	_, err := aliClient.TradeRefund(p)
	if err != nil {
		return false
	}
	return true
}
